﻿using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using TootlsBase.IFunction.IOfficeHelper;

namespace TootlsBase.Function.OfficeHelper
{
    /// <summary>
    ///基於NOPI開發 ExeclHelper工具類
    ///<para>作者： 尹文科</para>
    ///<para>時間： 2020-1-3</para>
    /// </summary>
    public class ExeclHelper : IExeclHelper
    {
        /// <summary>
        /// 讀取Execl返回DataSet(DataSet中Tables的名稱根據頁簽《sheet》名稱來決定的)
        /// <para>例如：D：\测试.xls</para>
        /// </summary>
        /// <param name="filePath">文件路徑</param>
        /// <returns>返回DataSet數據集</returns>
        public DataSet ImportExcelToDataSet(string filePath)
        {
            //聲明工作簿workBook對像
            IWorkbook wkBook = null;
            FileStream fsRead = null;
            try
            {
                if (!File.Exists(filePath)) throw new Exception("路徑不存在，請檢查路徑是否正確");
                DataSet dataSet = new DataSet();
                //創建一個工作簿workBook對象
                fsRead = new FileStream(filePath, FileMode.Open);
                //判斷Execl版本
                if (filePath.IndexOf(".xlsx") > 0)
                {
                    // 如果是2007+的Excel版本
                    wkBook = new XSSFWorkbook(fsRead);
                }
                else
                {
                    //如果是2003-的Excel版本
                    wkBook = new HSSFWorkbook(fsRead);
                }
                //遍歷wkBook中的每個工作表Sheet
                for (int i = 0; i < wkBook.NumberOfSheets; i++)
                {
                    //創建DataTable用來存儲當前sheet數據
                    DataTable dt = new DataTable();
                    //獲取每個工作表對象
                    ISheet sheet = wkBook.GetSheetAt(i);
                    //獲取當前sheet名稱
                    dt.TableName = sheet.SheetName.ToString().Trim().ToUpper();
                    //獲取每個工作表的行
                    for (int j = 0; j <= sheet.LastRowNum; j++)
                    {
                        //獲取工作表中的每一行
                        IRow currentRow = sheet.GetRow(j);
                        //創建DataTable行
                        DataRow dataRow = dt.NewRow();
                        if (j == 0)
                        {
                            //遍歷當前行中的每個單元格
                            for (int k = 0; k < currentRow.LastCellNum; k++)
                            {
                                //獲取每個單元格
                                ICell cell = currentRow.GetCell(k);
                                //設置當前DataTable列明
                                DataColumn column = new DataColumn(cell.StringCellValue);
                                //填充列名
                                dt.Columns.Add(column);
                            }
                        }
                        else
                        {
                            //遍歷當前行中的每個單元格
                            for (int k = 0; k < currentRow.LastCellNum; k++)
                            {
                                //獲取每個單元格
                                ICell cell = currentRow.GetCell(k);
                                //如果單元格為空時将添加Null进去
                                if (cell == null)
                                {
                                    dataRow[k] = null;
                                }
                                //如果單元格為空字符串時将添加原本的值带进去
                                else if (cell.ToString().Trim() == "")
                                {
                                    dataRow[k] = cell.ToString();
                                }
                                else
                                {
                                    // 獲取單元格中的類型
                                    CellType cellType = cell.CellType;
                                    //判斷當前單元格的數據類型
                                    switch (cellType)
                                    {
                                        case CellType.Numeric: //數字
                                            short format = cell.CellStyle.DataFormat;
                                            //对时间格式（2015.12.5、2015/12/5、2015-12-5等）的处理
                                            if (format == 14 || format == 31 || format == 57 || format == 58)
                                                dataRow[k] = cell.DateCellValue.ToString();
                                            else
                                                dataRow[k] = cell.NumericCellValue;
                                            break;
                                        case CellType.String: //字符串
                                            dataRow[k] = cell.StringCellValue;
                                            break;
                                        case CellType.Boolean://布爾值
                                            dataRow[k] = cell.BooleanCellValue;
                                            break;
                                    }
                                }
                            }
                            //向DataTable填充每一行數據
                            dt.Rows.Add(dataRow);
                        }
                    }
                    //向DataSet填充數據
                    dataSet.Tables.Add(dt);
                }
                wkBook.Close();//关闭文件流
                return dataSet;
            }
            catch (Exception ex)
            {
                wkBook.Close();//关闭文件流
                throw ex;
            }
        }
        /// <summary>
        /// 根據DataSet匯出Execl(DataSet中Tables的名稱決定頁簽《sheet》名稱)
        /// <para>使用方法：filePath（文件存儲路徑） : D:/，exportName（Execl文件名稱）：test，exportFormat（Execl匯出格式）：xlsx或xls</para>
        /// <para>文件生成樣式為：D:/測試.xlsx或者D:/測試.xls</para>
        /// <para>匯出結果：成功為：OK,匯出成功，失敗為：NO,失敗原因</para>
        /// </summary>
        /// <param name="dataSet">多表數據集</param>
        /// <param name="filePath">匯出路徑</param>
        /// <param name="exportName">Execl名稱</param>
        /// <param name="exportFormat">Execl後綴</param>
        /// <returns>OK,匯出成功;NO,失敗原因</returns>
        public string ExportExcelToDataSet(DataSet dataSet, string filePath, string exportName, string exportFormat)
        {
            //創建工作簿對象
            IWorkbook hssfworkbook = null;
            FileStream file = null;
            if (dataSet.Tables.Count < 1) throw new Exception("多表數據集不能位空");
            if (filePath.ToString().Trim() == "" || filePath == null) throw new Exception("匯出路徑異常，請核對路徑是否正確");
            if (exportName.ToString().Trim() == "" || exportName == null) throw new Exception("Execl名稱異常，請核對Execl名稱是否正確");
            if (exportFormat.ToString().Trim() == "" || exportFormat == null) throw new Exception("Execl後綴異常，請核對Execl後綴是否正確");
            try
            {
                switch (exportFormat.ToString().Trim().ToLower())
                {
                    case "xlsx": //如果是2003-的Excel版本
                        hssfworkbook = new XSSFWorkbook();
                        break;
                    case "xls": //如果是2007+的Excel版本
                        hssfworkbook = new HSSFWorkbook();
                        break;
                }
                ICellStyle style = GetCellStyle(hssfworkbook, HorizontalAlignment.Center, VerticalAlignment.Center, short.MinValue, 10, false);
                for (int i = 0; i < dataSet.Tables.Count; i++)
                {
                    ISheet sheet = hssfworkbook.CreateSheet(dataSet.Tables[i].TableName) as ISheet;//创建sheet
                    IRow row = sheet.CreateRow(0) as IRow;//锁定sheet第一行
                    for (int j = 0; j < dataSet.Tables[i].Columns.Count; j++)//获取DataTable列总条数依次循环
                    {
                        row.CreateCell(j).SetCellValue(dataSet.Tables[i].Columns[j].ColumnName);//填充sheet第一行标题内容
                        row.GetCell(j).CellStyle = style;
                    }
                    for (int g = 0; g < dataSet.Tables[i].Rows.Count; g++)//获取DataTable行总条数依次循环
                    {
                        row = sheet.CreateRow(g + 1) as IRow;//锁定除sheet第一行外的每一行
                        for (int j = 0; j < dataSet.Tables[i].Columns.Count; j++)//获取DataTable列总条数依次循环
                        {
                            row.CreateCell(j).SetCellValue(dataSet.Tables[i].Rows[g][j].ToString());//将DataTable数据填充sheet内容中
                            row.GetCell(j).CellStyle = style;
                        }
                    }
                }
                //寫入，把內存中的workBook對象寫入到磁盤上
                file = new FileStream(filePath + "\\" + exportName + "." + exportFormat, FileMode.Create);
                hssfworkbook.Write(file);
                hssfworkbook.Close();//关闭文件流
                file.Close();
                file.Dispose(); //释放文件流
                return "OK,匯出成功";
            }
            catch (Exception ex)
            {
                hssfworkbook.Close();//关闭文件流
                file.Close();
                file.Dispose(); //释放文件流
                return "NO," + ex.Message;
            }
        }
        /// <summary>
        /// 设置样式
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="hAlignment">水平布局方式</param>
        /// <param name="vAlignment">垂直布局方式</param>
        /// <param name="boldWeight">字体加粗 (short.MaxValue）</param>
        /// <param name="fontPonint">字体大小</param>
        /// <param name="isBorder">是否需要边框 true是</param>
        /// <returns></returns>
        private ICellStyle GetCellStyle(IWorkbook workbook, HorizontalAlignment hAlignment, VerticalAlignment vAlignment, short boldWeight, short fontPonint, bool isBorder)
        {
            try
            {
                ICellStyle cellstyle = workbook.CreateCellStyle();
                cellstyle.Alignment = hAlignment; //水平居中
                cellstyle.VerticalAlignment = vAlignment; //垂直居中
                if (isBorder)
                {
                    cellstyle.BorderBottom = BorderStyle.Thin;
                    cellstyle.BorderLeft = BorderStyle.Thin;
                    cellstyle.BorderRight = BorderStyle.Thin;
                    cellstyle.BorderTop = BorderStyle.Thin;
                }
                IFont cellStyleFont = (IFont)workbook.CreateFont(); //创建字体
                cellStyleFont.Boldweight = boldWeight; //字体加粗
                cellStyleFont.FontHeightInPoints = fontPonint; //字体大小
                cellstyle.SetFont(cellStyleFont); //将字体绑定到样式
                return cellstyle;
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }
    }
}
